package com.wswy.wzcx.ui.pay

import android.app.Activity
import android.arch.lifecycle.LiveData
import android.arch.lifecycle.MutableLiveData
import android.content.Context
import android.os.SystemClock
import android.text.TextUtils
import com.blankj.utilcode.util.SPUtils
import com.che.libcommon.api.BaseResult
import com.che.libcommon.api.ProgressDialogObserver
import com.che.libcommon.utils.ToastUtils
import com.che.libcommon.utils.optional.Optional
import com.wswy.wzcx.api.Api
import com.wswy.wzcx.model.DataCenter
import com.wswy.wzcx.model.PaymentOrder
import com.wswy.wzcx.model.coupon.CouponModel
import com.wswy.wzcx.model.coupon.CouponResp
import com.wswy.wzcx.model.pay.OrderStatus
import com.wswy.wzcx.model.pay.PayStyleModel
import com.wswy.wzcx.model.reSend
import com.wswy.wzcx.module.GlobalConfigManager
import com.wswy.wzcx.module.base.PayViewModel
import com.wswy.wzcx.module.base.Resource
import com.wswy.wzcx.module.base.SingleLiveData
import com.wswy.wzcx.module.base.onResult
import com.wswy.wzcx.ui.njdb.NjdbUtils
import com.wswy.wzcx.utils.ImageUtils
import com.wswy.wzcx.utils.RxUtils
import io.reactivex.Flowable
import io.reactivex.FlowableSubscriber
import io.reactivex.Single
import io.reactivex.observers.ResourceObserver
import io.reactivex.schedulers.Schedulers
import io.reactivex.subscribers.ResourceSubscriber
import timber.log.Timber
import java.io.File
import java.util.concurrent.TimeUnit
import kotlin.math.abs

class PayOrderViewModel : PayViewModel() {

    companion object{
        private const val KEY_LAST_CONTACT_NAME = "sp_pay_contact_name"
    }

    lateinit var payOrder : PayOrder

    //罚款代缴
    private val payFineLiveData = MutableLiveData<PayFineData>()

    //违章代办
    private val payWzdbLiveData = MutableLiveData<PayWzdbData>()

    //年检代办
    private val payNjdbLiveData = MutableLiveData<PayNjdbData>()

    //订单支付状态
    private val payOrderStatusLiveData = MutableLiveData<Resource<OrderStatus?>>()

    //优惠券
    private val couponRespLiveData = MutableLiveData<Resource<CouponResp?>>()

    private var payFlag = false

    fun getPayBaseData():PayBaseData? = when(payOrder.type){
        PayOrder.TYPE_WZDB -> payWzdbLiveData.value
        PayOrder.TYPE_FKDJ -> payFineLiveData.value
        PayOrder.TYPE_NJDB -> payNjdbLiveData.value
        else -> null
    }

    fun setPayStyle(newType:Int){
        getPayBaseData()?.payStyle = newType
    }


    fun setPreFineInfo(preFineInfo: PreFineInfo){
        payFineLiveData.value = PayFineData(preFineInfo)
    }

    fun setWzdbData(wzdbData: PayWzdbData){
        payWzdbLiveData.value = wzdbData
    }

    fun setNjdbData(njdbData: PayNjdbData){
        payNjdbLiveData.value = njdbData
    }

    fun getLastContactName():String?{
        return SPUtils.getInstance().getString(KEY_LAST_CONTACT_NAME)
    }

    fun setCoupon(id:Long,num:String?,couponModel: CouponModel?){
        getPayBaseData()?.setCoupon(id, num,couponModel)
        when(payOrder.type){
            PayOrder.TYPE_WZDB -> {
                payWzdbLiveData.reSend()
            }
            PayOrder.TYPE_FKDJ -> {
                payFineLiveData.reSend()
            }
            PayOrder.TYPE_NJDB -> {
                payNjdbLiveData.reSend()
            }
        }

    }

    //获取优惠券
    fun reloadCouponList(){
        //罚款代缴 优惠券
        if (this::payOrder.isInitialized && payOrder.type == PayOrder.TYPE_FKDJ){
            val conf = GlobalConfigManager.getInstance().sysConf.couponActivityConf;
            if (TextUtils.equals(conf?.value,"1")){
                addRun(Api.get().couponList().onResult(couponRespLiveData))
            }
        }

    }

    /////--- 罚款代缴
    fun setQuickService(quick:Boolean){
        payFineLiveData.value?.quickService = quick
        payFineLiveData.reSend()
    }

    fun startFinePay(activity:Activity){

        val payFineData = payFineLiveData.value
        val fineData = payFineData?.preFineInfo

        if (fineData == null){
            ToastUtils.showText("数据错误")
            return
        }
        val value = object : ProgressDialogObserver<PaymentOrder>(activity, "提示", "正在调起支付") {

            override fun onApiResult(map: PaymentOrder?) {

                map?.run {
                    //请求支付成功
                    if (isSuccess){
                        activity.let {act ->
                            if (!act.isFinishing){
                                payStyle = payFineData.payStyle
                                bizType = "fkdj"

                                //调起支付
                                startPay(act,this)

                                //成功，清除缓存
                                ImageUtils.clearCache()
                            }
                        }
                    }else{
                        ToastUtils.showText("请求支付失败，请重试")
                    }

                }

            }

            override fun onApiError(result: BaseResult<*>?) {
                toastErrorMsg(result)
            }
        }



        if (!fineData.img.isNullOrEmpty()){

            val subscribeWith = Single.just<File>(File(fineData.img)).observeOn(Schedulers.io()).map { file ->

                ImageUtils.compress(file.absolutePath)
            }.flatMap {

                val key = "image"

                Api.get().uploadFiles("fkdj", mapOf(key to it)).map {
                    it.get(key)?.objectKey
                }

            }.flatMap { file ->

                val tel = DataCenter.get().userMode?.mobile

                Api.get().submitFKDJMode(fineData.fineNo!!,
                        fineData.fineName!!,
                        tel!!,
                        fineData.fineFee.toString(),
                        fineData.serviceFee.toString(),
                        fineData.fineDate,
                        payFineData.payStyle.toString(),
                        file, payFineData.quickService, false, payFineData.couponId)
            }
                    .subscribeWith(
                            value)

            addRun(subscribeWith)

        }else{
            val tel = DataCenter.get().userMode?.mobile

            addRun(Api.get().submitFKDJMode(fineData.fineNo!!,
                    fineData.fineName!!,
                    tel!!,
                    fineData.fineFee.toString(),
                    fineData.serviceFee.toString(),
                    fineData.fineDate,
                    payFineData.payStyle.toString(),
                    null,payFineData.quickService,true,payFineData.couponId)
                    .subscribeWith(value))
        }

    }


    ///// -----  违章代办
    fun startWzdbPay(activity: Activity,phone:String,name:String){
        val wzdbData = payWzdbLiveData.value

        if (wzdbData == null){
            ToastUtils.showText("数据错误")
            return
        }

        SPUtils.getInstance().put(KEY_LAST_CONTACT_NAME,name)

        val value = object : ProgressDialogObserver<PaymentOrder>(activity, "提示", "正在调起支付") {

            override fun onApiResult(map: PaymentOrder?) {

                map?.run {
                    //请求支付成功
                    if (isSuccess){
                        activity.let {act ->
                            if (!act.isFinishing){
                                payStyle = wzdbData.payStyle
                                bizType = "wzdb"
                                //调起支付
                                startPay(act,this)
                                payFlag = true
                                //成功，清除缓存
                                ImageUtils.clearCache()
                            }
                        }
                    }else{
                        ToastUtils.showText("请求支付失败，请重试")
                    }

                }

            }

            override fun onApiError(result: BaseResult<*>?) {
                toastErrorMsg(result)
            }
        }


        addRun(Api.get().payWZDB(wzdbData.wzdbOrderInfo.orderNo,wzdbData.payStyle.toString(),phone,name).subscribeWith(value))

    }


    /////  年检代办
    fun startNjdbPay(activity: Activity){
        val njdbData = payNjdbLiveData.value

        if (njdbData == null){
            ToastUtils.showText("数据错误")
            return
        }

        val map = hashMapOf<String,String?>()

        map["contacts"] = njdbData.contacts
        map["mobile"] = njdbData.mobile
        map["address"] = njdbData.address
        map["carNo"] = njdbData.carNo
        map["payType"] = njdbData.payStyle.toString()

        //上传文件
        val files = NjdbUtils.getImgFiles(activity,njdbData.userCarInfo.id).mapKeys {
            when(it.key){
                "Z1" -> "compulsoryInsuranceCopy"
                else -> it.key
            }
        }
        Single.just(map).observeOn(Schedulers.io()).flatMap { data ->

            kotlin.runCatching {
                Api.get().uploadFiles("njdb",files).compose(RxUtils.switch2io()).blockingGet()?.forEach { (t, u)
                    ->
                    u?.objectKey?.let {
                        data[t] = it
                    }
                }
            }
            Single.just(data)
        }.flatMap {
            Api.get().createInspection(it)
        }.subscribe(object : ProgressDialogObserver<PaymentOrder>(activity,"提示","正在提交订单，请稍后"){
            override fun onApiResult(t: PaymentOrder?) {

                if (t != null && t.isSuccess){
                    //成功
                    //必须，设置金额
                    t.payStyle = njdbData.payStyle
                    t.bizType = "njdb"
                    //调起支付
                    if (!activity.isFinishing){
                        startPay(activity,t)
                    }
                }else{
                    ToastUtils.showText("创建订单失败，请稍后重试")
                }
            }

            override fun onApiError(result: BaseResult<*>?) {
                toastErrorMsg(result)
            }
        })

    }

    // 检查支付状态
    fun checkPay(){
        if (!payFlag){
            return
        }
        payFlag = false
        paymentOrder?.run {
            if (payStyle == PayStyleModel.ALIPAY_CHECAR.code || payStyle == PayStyleModel.WECHAT_CHECAR.code){


                addRun(Single.fromCallable {

                    var ptime = System.currentTimeMillis()
                    for (i in 0..3){

                        val f =   (System.currentTimeMillis() - ptime) - TimeUnit.SECONDS.toMillis(2)
                        if (ptime >0 && f < 0){
                            SystemClock.sleep(abs(f))
                        }

                        val data = kotlin.runCatching {
                            Api.get().checkPayStatus(orderNo, payStyle).blockingGet()
                        }

                        val r = data.getOrNull()?.orNull()
                        if (data.getOrNull()?.orNull()?.payStatus == true){
                            return@fromCallable Optional.ofNullable(r)
                        }

                        ptime = System.currentTimeMillis()

                    }
                    Optional.ofNullable(null as? OrderStatus?)
                }.compose(RxUtils.io2main()).onResult(payOrderStatusLiveData))

            }
        }
    }

    fun getFineLiveData (): LiveData<PayFineData> = payFineLiveData

    fun getWzdbLiveData():LiveData<PayWzdbData> = payWzdbLiveData

    fun getCouponRespLiveData() : LiveData<Resource<CouponResp?>> = couponRespLiveData

    fun getPayOrderStatusLiveData():LiveData<Resource<OrderStatus?>> = payOrderStatusLiveData
}